import os
import sys
import time
import glob
import shutil
import random
import subprocess

import locate_mypyutils
import locate_mypyprojectinstaller
import mypyutils.files
import mypyutils.modules

DJANGO_FILENAME = 'Django-1.2.1.tar.gz'
DJANGO_CMS_FILENAME = 'django-cms-2.1.0.beta3.tar.gz'
DJANGO_REVERSION_FILENAME = 'django-reversion-1.3.1.tar.gz'
DJANGO_SOUTH_FILENAME = 'south-0.7.1.tar.gz'

def is_y(s):
    return not s or s.lower() == 'y'

def is_valid_file_name(s):
    return project_name and project_name.find(' ') == -1 and project_name.find('&') == -1

MYPYPROJECTCREATOR_DIR = os.path.dirname(os.path.abspath(__file__))

'''
Get all user input
'''
base_directory = raw_input('Enter base path of the project: ')

if os.path.isdir(base_directory):
    answer = raw_input('Directory already exists. Delete content? (Y/n/q): ')
    if is_y(answer):
        mypyutils.files.forced_rmtree(base_directory)
        time.sleep(0.5)
    elif answer.lower() == 'q':
        print 'Quit!'
        sys.exit()
            
while not os.path.isdir(base_directory):
    if os.path.isfile(base_directory):
        print 'Error: "' + base_directory + '" is an existing file not a directory!'
        sys.exit(-1)
        
    try:
        os.makedirs(base_directory)
    except:        
        print 'Error: "' + base_directory + '" is not a valid directory path!'
        print 'Current directory: ', os.getcwd()
        base_directory = raw_input('Enter base path of the project: ')
        
base_name = os.path.basename(base_directory)
while True:
    project_name = raw_input('Enter the name of the project (%s): ' % base_name) or base_name
    try:
        project_path = os.path.join(base_directory, project_name)
        if not os.path.isdir(project_path):
            os.mkdir(project_path)
        break
    except:        
        print 'Error: "' + project_name + '" is an invalid directory name!'

use_i18n = is_y(raw_input('Use internationalization? (Y/n): '))
use_django_cms = False #is_y(raw_input('Use django CMS? (Y/n): '))
create_expample_app = is_y(raw_input('Create an example app? (Y/n): '))
if use_django_cms or create_expample_app:
    use_django_auth = True
    use_django_admin = True
else:
    use_django_auth = is_y(raw_input('Use user login? (Y/n): '))
    use_django_admin = is_y(raw_input('Use admin? (Y/n): '))
use_django_reversion = is_y(raw_input('Use django-reversion? (Y/n): '))
use_django_south = is_y(raw_input('Use django South? (Y/n): '))
    
'''
Copy required libraries
'''
base_path = os.path.abspath(base_directory)

installer_path = os.path.join(base_path, 'installer', '')
installer_requirements_path = os.path.join(installer_path, 'requirements', '')

if os.path.isfile(installer_path):
    print 'Error: "', installer_path, '" is an existing file not a directory!'
    sys.exit(-1)
    
if not os.path.isdir(installer_path):
    os.mkdir(installer_path)

template_installer_path = os.path.join(MYPYPROJECTCREATOR_DIR, 'template_installer')
template_installer_requirements_path = os.path.join(template_installer_path, 'requirements')

template_installer_files = glob.glob(os.path.join(template_installer_path, '*'))
for file in template_installer_files:
    if os.path.isfile(file):
        shutil.copy2(file, installer_path)
      
mypyutils.modules.copy_module('mypyprojectinstaller', os.path.join(installer_path, 'mypyprojectinstaller'))
mypyutils.modules.copy_module('mypyutils', os.path.join(base_path, 'mypyutils'))
shutil.copy2(os.path.join(MYPYPROJECTCREATOR_DIR, 'locate_mypyutils.py'), project_path)

os.mkdir(installer_requirements_path)
shutil.copy(os.path.join(template_installer_requirements_path, DJANGO_FILENAME), installer_requirements_path)

if use_django_cms:
    shutil.copy2(os.path.join(template_installer_requirements_path, DJANGO_CMS_FILENAME), installer_requirements_path)
    
if use_django_reversion:
    shutil.copy2(os.path.join(template_installer_requirements_path, DJANGO_REVERSION_FILENAME), installer_requirements_path)
    
if use_django_south:
    shutil.copy2(os.path.join(template_installer_requirements_path, DJANGO_SOUTH_FILENAME), installer_requirements_path)

'''
Install virtualenv and required libraries + project creation
'''
current_dir = os.getcwd()
try:
    os.chdir(base_path)
    
    print '\nInstalling virtualenv and requirements...'
    result = subprocess.call(['python', os.path.join('installer', 'install.py')])
    if result != 0:
        print 'Error:', os.path.abspath(os.path.join('installer', 'install.py')), 'returned with a code of', result
        sys.exit(result)

    print '\nCreating project', project_name + '...'
    template_project_path = os.path.join(MYPYPROJECTCREATOR_DIR, 'template_project')
    
    mypyutils.files.copy_tree(template_project_path, project_path)
    
    secret_key = ''.join([random.choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])
        
    def get_outcomment_string(use_feature):
        return '' if use_feature else '# '
    
    replacement_dict = {
        '$project_name$': project_name,
        '$gettext$': 'gettext = lambda s: s',
        '$secret_key$': secret_key,
        '$i18n$': str(use_i18n),
        '$i18n_outcomment$': get_outcomment_string(use_i18n),
        '$django_auth_outcomment$': get_outcomment_string(use_django_auth),
        '$django_admin_outcomment$': get_outcomment_string(use_django_admin),
        '$django_reversion_outcomment$': get_outcomment_string(use_django_reversion),
        '$import_reversion_admin$': 'import reversion.admin' if use_django_reversion else '',
        '$model_admin$': 'reversion.admin.VersionAdmin' if use_django_reversion else 'admin.ModelAdmin',
        '$django_south_outcomment$': get_outcomment_string(use_django_south),
        '$exampleapp_name$': 'pollsexample' if create_expample_app else 'myapp',
        '$exampleapp_outcomment$': get_outcomment_string(create_expample_app),
    }
    
    replacement_files = [os.path.join(project_path, 'EXAMPLE_APACHE_CONFIG')]     
    replacement_files += glob.glob(os.path.join(project_path, '*.py'))
    replacement_files += glob.glob(os.path.join(project_path, 'settings', '*.py'))
    
    if create_expample_app:
        print "\nCopying example app..."
        template_apps_path = os.path.join(MYPYPROJECTCREATOR_DIR, 'template_apps')
        template_pollsexample_app_path = os.path.join(template_apps_path, 'pollsexample')
        pollsexample_app_path = os.path.join(project_path, 'apps', 'pollsexample', '')
        mypyutils.files.copy_tree(template_pollsexample_app_path, pollsexample_app_path)
        replacement_files += glob.glob(os.path.join(pollsexample_app_path, '*.py'))

    for file in replacement_files:
        mypyutils.files.replace_in_file(file, replacement_dict)

finally:
    os.chdir(current_dir)
    
    
print '\nDone. Have fun with', project_path, ':-)'
print '\nPS: You may want to replace the directory ' + os.path.join(project_path, 'mypyutils') + ' with'
print 'svn:externals https://mypyutils.googlecode.com/svn/trunk/mypyutils/ mypyutils'
print 'and ' + os.path.join(project_path, 'installer', 'mypyprojectinstaller') + ' with'
print 'svn:externals https://mypyprojectinstaller.googlecode.com/svn/trunk/mypyprojectinstaller/ mypyprojectinstaller'
print 'Also set the directory virtualenv to svn:ignore, because it gets recreated by mypyprojectinstaller.'
